package com.example.aidocengine.validator;

import com.example.aidocengine.common.constant.BusinessConstant;
import com.example.aidocengine.common.utils.ValidationUtils;
import com.example.aidocengine.mapper.DeviceInfoMapper;
import com.example.aidocengine.pojo.entity.DeviceInfo;
import com.example.aidocengine.pojo.entity.DeviceStateTransition;
import com.example.aidocengine.pojo.entity.PrimaryDeviceTemplate;
import com.example.aidocengine.pojo.entity.TemplatePlaceholderRules;
import com.example.aidocengine.pojo.vo.DeviceValidationVO;
import com.example.aidocengine.pojo.vo.TerminologyValidationVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class AdvancedPrimaryDeviceValidator {

    @Autowired
    private DeviceInfoMapper deviceInfoMapper;

    @Autowired
    private com.example.aidocengine.mapper.PrimaryDeviceTemplateMapper primaryDeviceTemplateMapper;
    @Autowired  
    private com.example.aidocengine.mapper.TemplatePlaceholderRulesMapper templatePlaceholderRulesMapper;
    @Autowired
    private com.example.aidocengine.mapper.DeviceStateTransitionMapper deviceStateTransitionMapper;

    // 缓存数据
    private List<PrimaryDeviceTemplate> deviceTemplates;
    private List<TemplatePlaceholderRules> placeholderRules;
    private List<DeviceStateTransition> stateTransitions;
    private Map<String, DeviceStateTransition> stateTransitionMap;
    private Map<String, java.util.List<DeviceStateTransition>> transitionsByCategory;

    @PostConstruct
    public void initCache() {
        refreshCache();
    }

    public void refreshCache() {
        try {
            deviceTemplates = primaryDeviceTemplateMapper.selectAllActive();
            placeholderRules = templatePlaceholderRulesMapper.selectAllActive();
            stateTransitions = deviceStateTransitionMapper.selectAllActive();
            
            // 构建状态转换映射
            stateTransitionMap = new HashMap<>();
            transitionsByCategory = new HashMap<>();
            if (stateTransitions != null) {
                for (DeviceStateTransition transition : stateTransitions) {
                    String key = transition.getDeviceCategory() + ":" + transition.getActionKeyword();
                    stateTransitionMap.put(key, transition);
                    transitionsByCategory
                        .computeIfAbsent(transition.getDeviceCategory(), k -> new java.util.ArrayList<>())
                        .add(transition);
                }
            }
            
            log.info("高级一次设备校验器缓存已刷新 - 模板数量:{}, 占位符规则:{}, 状态转换:{}", 
                deviceTemplates != null ? deviceTemplates.size() : 0,
                placeholderRules != null ? placeholderRules.size() : 0,
                stateTransitions != null ? stateTransitions.size() : 0);
        } catch (Exception e) {
            log.error("刷新高级校验器缓存失败", e);
            // 初始化为空集合，避免空指针异常
            if (deviceTemplates == null) deviceTemplates = new ArrayList<>();
            if (placeholderRules == null) placeholderRules = new ArrayList<>();
            if (stateTransitions == null) stateTransitions = new ArrayList<>();
            if (stateTransitionMap == null) stateTransitionMap = new HashMap<>();
            if (transitionsByCategory == null) transitionsByCategory = new HashMap<>();
        }
    }

    /**
     * 基于术语模板的复杂校验逻辑
     */
    public TerminologyValidationVO validateWithTemplate(String operationStep) {
        TerminologyValidationVO validation = new TerminologyValidationVO();
        validation.setOperationStep(operationStep);
        validation.setValidationType(BusinessConstant.VALIDATION_TYPE_PRIMARY_DEVICE);

        if (!StringUtils.hasText(operationStep)) {
            validation.setIsValid(false);
            // 统一到通用原则错误，避免前端出现非常规文案
            validation.setErrorMessage(BusinessConstant.ERROR_WRITING_PRINCIPLE_VIOLATION);
            return validation;
        }

        try {
            // 1. 首先检查设备双编是否存在
            DeviceValidationVO deviceValidation = validateDeviceDoubleCode(operationStep);
            if (!deviceValidation.getIsValid()) {
                validation.setIsValid(false);
                validation.setErrorMessage(deviceValidation.getErrorMessage());
                return validation;
            }

            // 2. 基于设备类型查找匹配的模板
            String deviceCategory = deviceValidation.getDeviceCategory();
            PrimaryDeviceTemplate matchedTemplate = findBestMatchingTemplate(operationStep, deviceCategory);
            
            if (matchedTemplate == null) {
                validation.setIsValid(false);
                validation.setErrorMessage(BusinessConstant.ERROR_WRITING_PRINCIPLE_VIOLATION);
                return validation;
            }

            // 3. 执行模板匹配校验
            boolean templateMatched = validateAgainstTemplate(operationStep, matchedTemplate);
            if (!templateMatched) {
                validation.setIsValid(false);
                validation.setErrorMessage(
                    matchedTemplate.getValidationMessage() != null ?
                        matchedTemplate.getValidationMessage() : BusinessConstant.ERROR_WRITING_PRINCIPLE_VIOLATION);
                return validation;
            }

            // 4. 校验状态转换逻辑
            boolean stateTransitionValid = validateStateTransition(operationStep, deviceCategory);
            if (!stateTransitionValid) {
                validation.setIsValid(false);
                validation.setErrorMessage(BusinessConstant.ERROR_WRITING_PRINCIPLE_VIOLATION);
                return validation;
            }

            validation.setIsValid(true);
            validation.setMatchedKeyword(deviceValidation.getDeviceDoubleCode());
            log.debug("高级一次设备校验通过：{}", operationStep);

        } catch (Exception e) {
            log.error("高级一次设备校验异常：{}", operationStep, e);
            validation.setIsValid(false);
            validation.setErrorMessage("校验过程中发生异常：" + e.getMessage());
        }

        return validation;
    }

    /**
     * 校验设备双编是否存在（复用现有逻辑）
     */
    private DeviceValidationVO validateDeviceDoubleCode(String operationStep) {
        DeviceValidationVO validation = new DeviceValidationVO();

        String deviceDoubleCode = ValidationUtils.extractContentFromBrackets(operationStep);
        validation.setDeviceDoubleCode(deviceDoubleCode);

        if (!StringUtils.hasText(deviceDoubleCode)) {
            validation.setIsValid(false);
            validation.setErrorMessage("未找到设备双编（括号内容）");
            return validation;
        }

        DeviceInfo deviceInfo = deviceInfoMapper.selectByDeviceDoubleCode(deviceDoubleCode);
        
        if (deviceInfo == null) {
            validation.setIsValid(false);
            validation.setErrorMessage("设备双编不存在于设备模板中");
            return validation;
        }

        validation.setIsValid(true);
        validation.setDeviceCategory(deviceInfo.getDeviceCategory());
        return validation;
    }

    /**
     * 查找最佳匹配的模板
     */
    private PrimaryDeviceTemplate findBestMatchingTemplate(String operationStep, String deviceCategory) {
        if (deviceTemplates == null || deviceTemplates.isEmpty()) {
            return null;
        }

        // 根据设备类型筛选候选模板
        return deviceTemplates.stream()
            .filter(template -> isDeviceCategoryMatched(template.getDeviceCategory(), deviceCategory))
            .filter(template -> template.getStatus() == 1) // 有效状态
            .min((t1, t2) -> Integer.compare(t1.getPriority(), t2.getPriority())) // 按优先级排序
            .orElse(null);
    }

    /**
     * 检查设备分类是否匹配
     */
    private boolean isDeviceCategoryMatched(String templateCategory, String deviceCategory) {
        if (!StringUtils.hasText(templateCategory) || !StringUtils.hasText(deviceCategory)) {
            return false;
        }

        // 精确匹配
        if (templateCategory.equals(deviceCategory)) {
            return true;
        }

        // 模糊匹配
        String templateLower = templateCategory.toLowerCase();
        String deviceLower = deviceCategory.toLowerCase();
        
        return templateLower.contains(deviceLower) || deviceLower.contains(templateLower);
    }

    /**
     * 根据模板校验操作步骤
     */
    private boolean validateAgainstTemplate(String operationStep, PrimaryDeviceTemplate template) {
        String templatePattern = template.getTemplatePattern();
        
        if (!StringUtils.hasText(templatePattern)) {
            return true;
        }

        // 将模板表达式转换为正则表达式
        String regex = convertTemplateToRegex(templatePattern);
        
        if (!StringUtils.hasText(regex)) {
            return true;
        }

        try {
            Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
            return pattern.matcher(operationStep).find();
        } catch (Exception e) {
            log.warn("模板正则匹配异常：{}", regex, e);
            return false;
        }
    }

    /**
     * 将模板表达式转换为正则表达式
     */
    private String convertTemplateToRegex(String templatePattern) {
        String regex = templatePattern;
        
        // 替换常见占位符
        regex = regex.replace("（XX主变）", "[\\u4e00-\\u9fa5\\w]+");
        regex = regex.replace("（XX线路）", "[\\u4e00-\\u9fa5\\w]+");
        regex = regex.replace("（XX母线）", "[\\u4e00-\\u9fa5\\w]+");
        regex = regex.replace("（初始状态）", "(冷备用|运行|停止|试验位置|工作位置)");
        regex = regex.replace("（目标状态）", "(冷备用|运行|停止|试验位置|工作位置)");
        
        // 转义特殊字符
        regex = regex.replace("（", "\\（").replace("）", "\\）");
        regex = regex.replace("【", "\\【").replace("】", "\\】");
        
        return regex;
    }

    /**
     * 校验状态转换逻辑
     */
    private boolean validateStateTransition(String operationStep, String deviceCategory) {
        // 优先按“由…转…”抽取状态对进行严格校验
        if (validateStateTransitionByStates(operationStep, deviceCategory)) {
            return true;
        }
        // 提取操作动词
        String actionKeyword = extractActionKeyword(operationStep);
        if (!StringUtils.hasText(actionKeyword)) {
            return false;
        }

        // 查找状态转换规则
        String key = deviceCategory + ":" + actionKeyword;
        DeviceStateTransition transition = stateTransitionMap.get(key);
        
        if (transition == null) {
            // 如果没有特定规则，使用通用规则
            return validateGeneralStateTransition(operationStep, actionKeyword);
        }

        // 根据规则校验状态转换
        return validateSpecificStateTransition(operationStep, transition);
    }

    /**
     * 提取操作动词
     */
    private String extractActionKeyword(String operationStep) {
        String[] actionKeywords = {
            "投入", "退出", "合上", "断开", "切换", "转换", 
            "启动", "停止", "分闸", "合闸", "投运", "停运"
        };
        
        for (String keyword : actionKeywords) {
            if (operationStep.contains(keyword)) {
                return keyword;
            }
        }
        
        return null;
    }

    /**
     * 通用状态转换校验
     */
    private boolean validateGeneralStateTransition(String operationStep, String actionKeyword) {
        // 简单的关键词匹配
        String[] validKeywords = {
            "投入", "退出", "合上", "断开", "切换", "转换",
            "启动", "停止", "分闸", "合闸", "投运", "停运"
        };
        
        for (String keyword : validKeywords) {
            if (actionKeyword.equals(keyword)) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * 特定状态转换校验
     */
    private boolean validateSpecificStateTransition(String operationStep, DeviceStateTransition transition) {
        // 这里可以实现更复杂的状态转换逻辑校验
        // 例如检查操作步骤中是否包含了正确的初始状态和目标状态描述
        
        String initialState = transition.getInitialState();
        String targetState = transition.getTargetState();
        
        if (!StringUtils.hasText(initialState) || !StringUtils.hasText(targetState)) {
            return true; // 如果没有状态要求，则通过
        }
        
        // 检查操作步骤是否描述了合理的状态转换
        boolean hasValidTransition = operationStep.contains(initialState) || operationStep.contains(targetState);
        
        return hasValidTransition;
    }

    /**
     * 直接从语句中提取“由…转…”的状态对，并与该设备分类可用状态转换表比对
     */
    private boolean validateStateTransitionByStates(String operationStep, String deviceCategory) {
        if (!StringUtils.hasText(operationStep) || !StringUtils.hasText(deviceCategory)) {
            return false;
        }
        String text = operationStep.replaceAll("\\s+", "");
        java.util.regex.Pattern p = java.util.regex.Pattern.compile("由[（(]?([^）)转为→到至]{1,12})[）)]?(?:转为|转|→|到|至)[（(]?([^）)]{1,12})[）)]?");
        java.util.regex.Matcher m = p.matcher(text);
        if (!m.find()) {
            return false;
        }
        String initial = m.group(1);
        String target = m.group(2);
        if (!StringUtils.hasText(initial) || !StringUtils.hasText(target)) {
            return false;
        }
        if (initial.equals(target)) {
            return false; // 禁止同状态→同状态
        }
        java.util.List<DeviceStateTransition> list = transitionsByCategory != null ? transitionsByCategory.get(deviceCategory) : null;
        if (list == null || list.isEmpty()) {
            return false;
        }
        for (DeviceStateTransition t : list) {
            if (initial.equals(t.getInitialState()) && target.equals(t.getTargetState())) {
                return true;
            }
        }
        return false;
    }
}
